#include "Main.h"
#include "Config.h"
#include "Input.h"
#include "Draw.h"
#include "MenuBar.h"
#include "MenuItem.h"
#include "Column.h"
#include "Program.h"
#include "Namespace.h"
#include "Class.h"
#include "ClassContent.h"
#include <string>

FunctionViewer::Input M_Input;
FunctionViewer::Draw M_Draw;
FunctionViewer::Main M_Main;
FunctionViewer::Program M_Program;
FunctionViewer::Config M_Config;

FunctionViewer::MenuBar Bar;
FunctionViewer::MenuItem *file, *edit, *help;
FunctionViewer::Column *column1, *column2;

void FunctionViewer::Main::Initialize() {
	glClearColor(1, 1, 1, 0.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, M_Config.screenwidth, M_Config.screenheight, 0, 0, 1);
	glMatrixMode(GL_MODELVIEW);
}

void FunctionViewer::Main::PrintProgramStructure() {
	M_Program.PrintProgramStructure();
}

/*FunctionViewer::Program FunctionViewer::Main::LoadFile(char* filename) {
}*/

void FunctionViewer::Main::Test() {
	Program program1;
	Namespace *_namespace1, *_namespace2, *_innamespace1, *_innamespace2;
	Class *_class1, *_class2, *_class3, *_class4, *_class5, *_class6;
	ClassContent *_content1;

	program1.SetName("Supertest");

	_namespace1 = program1.CreateNamespace("Namespacetest1");
	_namespace2 = program1.CreateNamespace("Namespacetest2");

	_innamespace1 = _namespace1->CreateInNamespace(_namespace1, "InNamespacetest1");
	_innamespace2 = _namespace1->CreateInNamespace(_namespace1, "InNamespacetest2");

	_class1 = _namespace1->CreateClass("Classtest1");
	_class2 = _namespace1->CreateClass("Classtest2");
	_class3 = _namespace2->CreateClass("Classtest3");
	_class4 = _innamespace1->CreateClass("Classtest4");
	_class5 = _innamespace1->CreateClass("Classtest5");
	_class6 = _innamespace2->CreateClass("Classtest6");

	_content1 = _class1->CreateContent("void", "ContentTest1", "Test");

	program1.PrintProgramStructure();
}

void FunctionViewer::Main::Menu() {
	Bar.init(M_Config, M_Draw);

	file = Bar.createMenuItem("file");

	//column1->Init(1, 1000, (M_Config.screenheight - 100));
	//column2->Init(2, (M_Config.screenwidth - 1000), (M_Config.screenheight - 100));
}

void Draw() {
	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
	Bar.drawMenu();
	file->drawItem();

	//column1->Draw();
	//column2->Draw();

	//M_Main.LoadFile("test.txt");
	//M_Draw.text(100, 100, 1, 0, 0, "LOOOL");
	glFlush();
}

void KeyHandler(unsigned char key, int x, int y) {
	M_Input.KeyboardInput(key, x, y);
}

void MouseHandler(int button, int state, int x, int y) {
	M_Input.MouseInput(button, state, x, y);
}

void FunctionViewer::Main::LoadFile(char* filename) {
	std::string line;
	std::ifstream loadFile(filename);
	float iAdd = (float) M_Config.screenheight;
	std::cout << iAdd << std::endl;

	float i = 0;
	if (loadFile.is_open()) {
		while (loadFile.good()) {
			std::getline(loadFile, line);
			std::cout << line << std::endl;

			char * drawText = new char[line.size() + 1];
			std::copy(line.begin(), line.end(), drawText);
			drawText[line.size()] = '\0';
			M_Draw.text(-0.95, (0.9 - i), 0, 0, 0, drawText);
			i += 0.08;
		}
		loadFile.close();
	}
	else {
		printf("File could not open!");
	}
}

int main(int argc, char** argv) {
	M_Config.screenwidth = GetSystemMetrics(SM_CXSCREEN) - 200;
	M_Config.screenheight = GetSystemMetrics(SM_CYSCREEN) - 150;
	std::cout << "Width: " << M_Config.screenwidth << std::endl << "Height: " << M_Config.screenheight << std::endl;
	M_Config.title = "Function Viewer";
#ifdef DEBUG_STRING
	std::cout << "Works1" << std::endl;
#endif

	glutInit(&argc, argv);
#ifdef DEBUG_STRING
	std::cout << "Works2" << std::endl;
#endif

	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);	
	glutInitWindowSize(M_Config.screenwidth, M_Config.screenheight);
	//glutInitWindowSize(FunctionViewer::screenwidth, FunctionViewer::screenheight);
	glutInitWindowPosition(100, 75);
	glutCreateWindow(M_Config.title);
#ifdef DEBUG_STRING
	std::cout << "Works3" << std::endl;
#endif

	//glutCreateWindow(FunctionViewer::title);
	M_Main.Initialize();
#ifdef DEBUG_STRING
	std::cout << "Works4" << std::endl;
#endif

	M_Main.Test();
	M_Main.Menu();
#ifdef DEBUG_STRING
	std::cout << "Works5" << std::endl;
#endif

	//M_Main.PrintProgramStructure();
	glutDisplayFunc(Draw);
	glutKeyboardFunc(KeyHandler);
	glutMouseFunc(MouseHandler);
	glutMainLoop();
	return 0;
}